package com.hmy.infrastructure.service.aliemas.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.aliyun.push20160801.Client;
import com.aliyun.push20160801.models.PushRequest;
import com.aliyun.push20160801.models.PushResponse;
import com.hmy.ccp.error.exception.HMYRuntimeException;
import com.hmy.infrastructure.api.bo.request.aliemaspush.MessageAccountPushRequest;
import com.hmy.infrastructure.api.bo.request.aliemaspush.MessageDevicePushRequest;
import com.hmy.infrastructure.common.constant.AliEmasConstant;
import com.hmy.infrastructure.common.properties.AliEMASPushProperties;
import com.hmy.infrastructure.service.aliemas.IAliEmasPushService;
import com.hmy.infrastructure.service.aliemas.dto.AliEmasMsgInfoDto;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class AliEmasPushServiceImpl implements IAliEmasPushService {

    @Resource
    private AliEMASPushProperties aliEMASPushProperties;

    @Resource
    private Client client;

    @Override
    public Boolean sendMessageByDevices(MessageDevicePushRequest messageDevicePushRequest) {
        PushResponse iosResponse = null;
        PushResponse androidResponse = null;
        log.info("sendMessageByDevices MessageDevicePushRequest:{}", JSON.toJSONString(messageDevicePushRequest));
        try {
            List<String> deviceIds = messageDevicePushRequest.getDeviceIds();
            if (CollectionUtil.isNotEmpty(deviceIds)) {
                /*step1.封装dto入参*/
                AliEmasMsgInfoDto aliEmasMsgInfoDto = new AliEmasMsgInfoDto();
                aliEmasMsgInfoDto.setTargetBodyIds(deviceIds);
                aliEmasMsgInfoDto.setTargetBodyIdsStr(aliEmasMsgInfoDto.targetBody2Str(deviceIds));
                aliEmasMsgInfoDto.setMessageTitle(messageDevicePushRequest.getMessageTitle());
                aliEmasMsgInfoDto.setMessageBody(messageDevicePushRequest.getMessageBody());

                /*step2.创建emas PushRequest结构体*/
                aliEMASPushProperties.setTarget(AliEmasConstant.ALI_EMAS_PUSH_Target_DEVICE);
                PushRequest pushRequest = aliEmasPushRequestBuilder(aliEMASPushProperties, aliEmasMsgInfoDto);

                /*step3.推送消息*/
                // 推送目标 不同appkey要分别推送
                pushRequest.setAppKey(Long.valueOf(aliEMASPushProperties.getIosAppKey()));
                iosResponse = client.push(pushRequest);

                pushRequest.setAppKey(Long.valueOf(aliEMASPushProperties.getAndroidAppKey()));
                androidResponse = client.push(pushRequest);
            }
            if (Objects.nonNull(iosResponse)) {
                log.info("ios sendMessageByDevices RequestId: {}, MessageID: {}", iosResponse.getBody().getRequestId(), iosResponse.getBody().getMessageId());
            }
            if (Objects.nonNull(androidResponse)) {
                log.info("android sendMessageByDevices RequestId: {}, MessageID: {}", androidResponse.getBody().getRequestId(), androidResponse.getBody().getMessageId());
            }
        } catch (Exception e) {
            log.error("消息推送失败", e);
            throw new HMYRuntimeException(404001001);
        }
        return true;
    }

    @Override
    public Boolean sendMessageByAccounts(MessageAccountPushRequest messageAccountPushRequest) {
        PushResponse iosResponse = null;
        PushResponse androidResponse = null;
        log.info("sendMessageByAccounts MessageAccountPushRequest:{}", JSON.toJSONString(messageAccountPushRequest));
        try {
            List<Long> accountIdList = messageAccountPushRequest.getAccounts();
            if (CollectionUtil.isNotEmpty(accountIdList)) {
                List<String> accountIds = accountIdList.stream().map(Objects::toString).collect(Collectors.toList());
                /*step1.封装dto入参*/
                AliEmasMsgInfoDto aliEmasMsgInfoDto = new AliEmasMsgInfoDto();
                aliEmasMsgInfoDto.setTargetBodyIds(accountIds);
                aliEmasMsgInfoDto.setTargetBodyIdsStr(aliEmasMsgInfoDto.targetBody2Str(accountIds));
                aliEmasMsgInfoDto.setMessageTitle(messageAccountPushRequest.getMessageTitle());
                aliEmasMsgInfoDto.setMessageBody(messageAccountPushRequest.getMessageBody());

                /*step2.创建emas PushRequest结构体*/
                aliEMASPushProperties.setTarget(AliEmasConstant.ALI_EMAS_PUSH_Target_ACCOUNT);
                PushRequest pushRequest = aliEmasPushRequestBuilder(aliEMASPushProperties, aliEmasMsgInfoDto);

                /*step3.推送消息*/
                // 推送目标 不同appkey要分别推送
                pushRequest.setAppKey(Long.valueOf(aliEMASPushProperties.getIosAppKey()));
                iosResponse = client.push(pushRequest);
                
                pushRequest.setAppKey(Long.valueOf(aliEMASPushProperties.getAndroidAppKey()));
                androidResponse = client.push(pushRequest);
            }
            if (Objects.nonNull(iosResponse)) {
                log.info("ios sendMessageByAccounts RequestId: {}, MessageID: {}", iosResponse.getBody().getRequestId(), iosResponse.getBody().getMessageId());
            }

            if (Objects.nonNull(androidResponse)) {
                log.info("android sendMessageByAccounts RequestId: {}, MessageID: {}", androidResponse.getBody().getRequestId(), androidResponse.getBody().getMessageId());
            }
        } catch (Exception e) {
            log.error("消息推送失败", e);
            throw new HMYRuntimeException(404001001);
        }
        return true;
    }

    private PushRequest aliEmasPushRequestBuilder(AliEMASPushProperties aliEMASPushProperties, AliEmasMsgInfoDto aliEmasMsgInfoDto) {
        PushRequest pushRequest = new PushRequest();
        // 推送目标
        pushRequest.setTarget(aliEMASPushProperties.getTarget()); //推送目标: DEVICE:推送给设备; ACCOUNT:推送给指定账号,TAG:推送给自定义标签; ALIAS: 按别名推送; ALL: 全推
        pushRequest.setTargetValue(aliEmasMsgInfoDto.getTargetBodyIdsStr());
        pushRequest.setDeviceType(AliEmasConstant.ALI_EMAS_PUSH_DEVICE_TYPE_ALL); // 设备类型 deviceType, iOS 设备: "iOS"; Android 设备: "ANDROID"; 全部: "ALL", 这是默认值.
        // 推送配置
        pushRequest.setPushType(AliEmasConstant.ALI_EMAS_PUSH_TYPE_NOTICE); // MESSAGE:表示消息(默认), NOTICE:表示通知
        pushRequest.setTitle(aliEmasMsgInfoDto.getMessageTitle()); // 消息的标题
        pushRequest.setBody(aliEmasMsgInfoDto.getMessageBody()); // 消息的内容
        // 推送配置: iOS
        pushRequest.setIOSBadge(1); // iOS 应用图标右上角角标
        pushRequest.setIOSMusic("default"); // iOS 通知声音
        pushRequest.setIOSApnsEnv(aliEMASPushProperties.getIOSApnsEnv());//iOS 的通知是通过 APNs 中心来发送的，需要填写对应的环境信息。'DEV': 表示开发环境 'PRODUCT': 表示生产环境
        pushRequest.setIOSRemind(true); //  消息推送时设备不在线（既与移动推送的服务端的长连接通道不通），则这条推送会做为通知，通过苹果的 APNs 通道送达一次。注意：**离线消息转通知仅适用于`生产环境`**
        pushRequest.setIOSRemindBody(aliEmasMsgInfoDto.getMessageBody());
        // 推送配置: Android
        pushRequest.setAndroidOpenType("APPLICATION"); // 点击通知后动作 'APPLICATION': 打开应用 'ACTIVITY': 打开应用 AndroidActivity 'URL': 打开 URL 'NONE': 无跳转
        pushRequest.setAndroidNotifyType("BOTH"); // 通知的提醒方式 ‘VIBRATE': 振动  'SOUND': 声音 'DEFAULT': 声音和振动 'NONE': 不做处理，用户自定义
//        pushRequest.setAndroidOpenUrl("http://www.alibaba.com");
        pushRequest.setAndroidMusic("default"); // Android 通知声音
        pushRequest.setAndroidPopupActivity("com.example.heimy_flutter_project.MainActivity"); //设置该参数后启动辅助弹窗功能, 此处指定通知点击后跳转的 Activity（辅助弹窗的前提条件：1. 集成第三方辅助通道；2. StoreOffline 参数设为 true）
        pushRequest.setAndroidPopupTitle(aliEmasMsgInfoDto.getMessageTitle()); //设置辅助弹窗通知的标题
        pushRequest.setAndroidPopupBody(aliEmasMsgInfoDto.getMessageBody()); //设置辅助弹窗通知的内容
        pushRequest.setAndroidNotificationBarType(50); //Android 自定义通知栏样式，取值：1-100
        pushRequest.setAndroidNotificationBarPriority(2); //Android 通知在通知栏展示时排列位置的优先级 -2 -1 0 1 2
        // 推送控制
        pushRequest.setStoreOffline(true); // 离线消息是否保存,若保存, 在推送时候，用户即使不在线，下一次上线则会收到，安卓中若为 false 则只走阿里云自有在线通道
        pushRequest.setAndroidTargetUserType(aliEMASPushProperties.getAndroidTargetUserType()); // 代表本次推送如果推送到华为、荣耀、vivo 通道，是一个正式通知，但本代码示例中这个值被厂商通道特有参数所覆盖
        pushRequest.setAndroidHuaweiReceiptId("RCPB01D5F2B"); // 华为厂商通道
        // 厂商通道通知分类
        pushRequest.setAndroidNotificationHuaweiChannel("8.0up");
        pushRequest.setAndroidNotificationChannel("8.0up"); // OPPO 通道私信通道 channel_id，以及通用安卓 channel_id
        pushRequest.setAndroidNotificationXiaomiChannel("116235"); //小米通道通知类型 channel_id
        pushRequest.setAndroidNotificationHonorChannel("NORMAL"); // 荣耀通道消息分类参数，对应荣耀通道 importance 参数
        pushRequest.setAndroidMessageHuaweiCategory("WORK");
        return pushRequest;
    }


}
